<template>
    <div class="cp-container-novak-chart-info">
        <div class="chart" ref="Chart"></div>
        <div class="tooltip" ref="TooltipEl">
            <div class="title">
            </div>
            <div class="data">
            </div>
        </div>
    </div>
</template>
<script>
/*
 斯蒂夫相图图表组件，展示详细数据
 */
import {numberLimit} from "@/common/OtherTools";
import Konva from "konva";
export default {
    props:{
        pointData:{  //点数据
            type:Array,
            default:()=>[],
        },
        padding:{
            type:Array,
            default:()=>[40,20,50,20],
        },
    },
    data() {
        this.lineColor = "#B8DBFF";  //线条颜色
        this.bgColor = '#1a83ff';  //填充背景颜色
        this.stage = {};  //舞台
        this.layer = {};  //画布
        this.width = 0;  //容器宽度
        this.height = 0;
        this.axisWidth = 0;  //坐标轴宽度
        this.axisHeight = 0;
        this.lineSquareNumber = 11;  //一侧线条上的格子数量
        this.lineSquareValue = 20;  //一侧线条上的格子值
        this.centrePoints = [];  //线条的中点坐标列表
        this.lableFormat = (i,index)=>{  //坐标轴刻度文字格式化函数
            return index*this.lineSquareValue;
        };
        return {};
    },
    watch:{
        pointData:{
            handler(newValue){
                this.$nextTick(()=>{
                    setTimeout(()=>{
                        this.drawRect(newValue);
                    },300);
                });
            },
            immediate:true,
        },
    },
    mounted(){
        let elData = this.getElData();
        this.stage = new Konva.Stage({
            container:this.getEl(),
            width:elData.width,
            height:elData.height,
        });
        this.layer = new Konva.Layer();
        this.stage.add(this.layer);
        this.width = this.stage.width();
        this.height = this.stage.height();
        this.axisWidth = this.width-this.padding[1]-this.padding[3];  //坐标轴宽度
        this.axisHeight = (this.height-this.padding[0]-this.padding[2]);  //坐标轴宽度
        this.centrePoints = [];  //线条中心点
        for(let i=0;i<3;i++){
            this.centrePoints.push([
                this.padding[3]+this.axisWidth/2,
                this.padding[0]+i*this.axisHeight/2,
            ]);
        }
    },
    methods:{
        isActive(){  //是否是当前活动的组件
            const el = this.$el;
            if(!el) return false;
            return !!(el.clientWidth || el.clientHeight);
        },
        getEl(){
            return this.$refs.Chart;
        },
        getTooltipEl(){
            return this.$refs.TooltipEl;
        },
        getElData(){  //获取元素基础数据
            const el = this.$el;
            if(!el) return;
            return el.getBoundingClientRect();
        },
        initData({lableFormat,lineSquareNumber,lineSquareValue}={}){  //初始化数据(外部调用)
            this.lineSquareValue = lineSquareValue || this.lineSquareValue;
            this.lineSquareNumber = lineSquareNumber || this.lineSquareNumber;
            this.lableFormat = lableFormat || this.lableFormat;
        },
        drawAxis(){  //绘制坐标轴
            const group = new Konva.Group({  //创建一个分组
                x: 0,
                y: 0,
                width: this.stage.width(),
                height: this.stage.height(),
                offsetX: 0,
                offsetY: 0,
            });
            const width = this.width;
            const axisWidth = this.axisWidth;  //坐标轴宽度
            const centrePoint = this.centrePoints;  //三条坐标轴中点
            for(let i=0;i<3;i++){
                let line = new Konva.Line({
                    points: [
                        this.padding[3],
                        centrePoint[i][1],
                        width-this.padding[1],
                        centrePoint[i][1],
                    ],
                    stroke: this.lineColor,
                    strokeWidth: 1,
                    lineJoin: 'round',
                });
                group.add(line);
                let squeareHeight = 10;  //轴标线长度
                let lineSquareWidth = axisWidth/2/this.lineSquareNumber;  //单个小格宽度
                for(let c=0;c<=this.lineSquareNumber*2;c++){
                    let isLeft = c<=this.lineSquareNumber;  //是左边的点
                    let a = isLeft?c:c-this.lineSquareNumber;
                    let isLong = a%2===0;  //是长刻度线
                    let line = new Konva.Line({
                        points: [
                            isLeft?centrePoint[i][0]-lineSquareWidth*a:centrePoint[i][0]+lineSquareWidth*a,
                            centrePoint[i][1],
                            isLeft?centrePoint[i][0]-lineSquareWidth*a:centrePoint[i][0]+lineSquareWidth*a,
                            centrePoint[i][1] + (isLong?squeareHeight*1.5:squeareHeight),
                        ],
                        stroke: this.lineColor,
                        strokeWidth: 1,
                        lineJoin: 'round',
                    });
                    if(isLong){
                        var text = new Konva.Text({
                            x: isLeft?centrePoint[i][0]-lineSquareWidth*a:centrePoint[i][0]+lineSquareWidth*a,
                            y: centrePoint[i][1] + squeareHeight*1.5 + 5 ,
                            text: this.lableFormat(i,a),
                            fontSize: 14,
                            fontFamily: 'Arial',
                            align: 'center',
                            fill: this.lineColor,
                        });
                        text.offsetX(text.width() / 2);
                        group.add(text);
                    }
                    group.add(line);
                }
            }
            group.zIndex(1);
            return group;
        },
        drawRect(pointData=[]){  //绘制矩形(可外部调用)
            if(this.dataGroup){
                this.dataGroup.destroy();
            }
            const textList = ["Ca/Mg","Na/Ca","(Na+K)/(Ca+Mg)","Na/K","Mg/K","Na/Mg"];  //点位顺序
            const pointLocation = ['left','right','right','right','left','left'];  //点对应的方向
            const group = new Konva.Group({  //创建一个分组
                x: 0,
                y: 0,
                width: this.stage.width(),
                height: this.stage.height(),
                offsetX: 0,
                offsetY: 0,
            });
            let pointList = [  //点数组
                [
                    this.computeXPoint(pointData[0],'left'),
                    this.centrePoints[0][1],
                ],
                [
                    this.computeXPoint(pointData[1],'right'),
                    this.centrePoints[0][1],
                ],
                [
                    this.computeXPoint(pointData[2],'right'),
                    this.centrePoints[1][1],
                ],
                [
                    this.computeXPoint(pointData[3],'right'),
                    this.centrePoints[2][1],
                ],
                [
                    this.computeXPoint(pointData[4],'left'),
                    this.centrePoints[2][1],
                ],
                [
                    this.computeXPoint(pointData[5],'left'),
                    this.centrePoints[1][1],
                ],
            ];
            group.add(new Konva.Line({  //添加多边形
                points: [].concat.apply([], pointList),
                fill: '#00D2FF',
                stroke: 'black',
                strokeWidth: 2,
                closed: true
            }));
            pointList.forEach((item,index)=>{  //添加文字以及点位
                let point = new Konva.Circle({
                    x: item[0],
                    y: item[1],
                    radius: 5,
                    fill: '#ff6060',
                    stroke: 'black',
                    strokeWidth: 1,
                });
                point.on('mousemove', (e)=>{  //添加鼠标移动事件
                    this.drawTooltip({
                        e:e.evt,
                        show:true,
                        data:{
                            title:textList[index],
                            data:pointData[index],
                        },
                    });
                    this.stage.container().style.cursor = 'pointer';
                });
                point.on('mouseout', ()=>{  //添加鼠标移动事件
                    this.drawTooltip({
                        show:false,
                    });
                    this.stage.container().style.cursor = 'default';
                });
                group.add(point);
                //绘制文字
                let text = new Konva.Text({
                    x: pointList[index][0],
                    y: pointList[index][1],
                    text:textList[index],
                    fontSize: 20,
                    fontFamily: 'Calibri',
                    fill: this.lineColor,
                    align: 'center',
                });
                if(pointLocation[index] == 'left'){
                    text.offsetX(text.width());
                }else{
                    text.offsetX(0);
                }
                text.offsetY(text.height()*1.2);
                group.add(text);
            });
            this.dataGroup = group;
            this.layer.add(group);
            const group1 = this.drawAxis();
            this.layer.add(group1);
            group.zIndex(0);
            group1.zIndex(1);
        },
        computeXPoint(x=0,location='left'){  //根据点数据计算x轴的相对位置
            x = Math.min(x,220);
            let maxValue = this.lineSquareNumber * this.lineSquareValue;
            let rate = x/maxValue;
            if(location=='left'){  //表示是左边的点
                return (this.axisWidth/2) - (this.axisWidth/2 * rate) + this.padding[3];
            }else{
                return (this.axisWidth/2) + (this.axisWidth/2 * rate) + this.padding[3];
            }
        },
        drawTooltip({e,data,show}={}){  //绘制提示框
            let el = this.getTooltipEl();
            if(!el) return;
            el.style.opacity = show?1:0;
            if(!show) return;
            let elData = el.getBoundingClientRect();
            let maxTop = [0,this.height-elData.height];  //top取值区间
            let maxLeft = [0,this.width-elData.width];
            el.style.top = numberLimit({
                value:e.offsetY,
                min:maxTop[0],
                max:maxTop[1],
            })+'px';
            el.style.left = numberLimit({
                value:e.offsetX,
                min:maxLeft[0],
                max:maxLeft[1],
            })+'px';
            let firstChild = el.firstChild;
            firstChild.textContent = data.title;
            let lastChild = el.lastChild;
            lastChild.textContent = data.data;
        },
    },
}
</script>
<style lang="scss" scoped>
.cp-container-novak-chart-info{
    width: 100%;
    height: 100%;
    position: relative;
    >.chart{
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 0;
    }
    >.tooltip{
        opacity: 0;
        position: absolute;
        top: 0;
        left: 0;
        width: fit-content;
        height: fit-content;
        z-index: 1;
        background-color: white;
        padding: 10px;
        border-radius: 13px;
        display: grid;
        grid-gap: 5px;
        pointer-events: none;
        color: black;
        border: 1px solid #00000070;
        box-sizing: border-box;
        box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.398);
        transition: all 0.2s;
        >.title{
            font-size: 17px;
            font-weight: bold;
        }
        >.data{
            font-size: 15px;
        }
    }
}
</style>